package com.hougong.im.httpcontroller;

import com.hougong.im.body.httpresponse.MyApplyAddFriendVo;
import com.hougong.im.body.httpresponse.SearchGroupVo;
import com.hougong.im.body.httpresponse.SearchUserVo;
import com.hougong.im.body.notice.AcceptOrRejectFriendNotice;
import com.hougong.im.body.notice.ApplyAddFriendNotice;
import com.hougong.im.common.GlobalCode;
import com.hougong.im.entity.*;
import com.hougong.im.mapper.*;
import com.hougong.im.pool.ConnPool;
import com.hougong.im.utils.JwtUtils;
import com.hougong.im.utils.R;
import com.hougong.im.utils.SendUtils;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 申请 方面的
 */
@RestController
@RequestMapping("/apply")
public class ApplyController {
    private static final Logger LOGGER = LoggerFactory.getLogger(ApplyController.class);

    @Autowired
    private ChatUserMapper chatUserMapper;
    @Autowired
    private ApplyAddfriendMapper applyAddfriendMapper;
    @Autowired
    private FriendMapper friendMapper;
    @Autowired
    private ChatGroupMapper groupMapper;
    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private ApplyEntergroupMapper applyEntergroupMapper;
    /**
     * 查询用户  模糊查询最多10条
     * @param
     * @return
     */
    @RequestMapping("/queryusers")
    @Transactional
    public R queryUsers(HttpServletRequest request){
        String token = request.getParameter("token");
        final Long tokenUid = JwtUtils.getTokenUid(token);
        String key = request.getParameter("key");
        List<SearchUserVo> searchUserVos = chatUserMapper.selectUserLike(key);
        for(SearchUserVo searchUserVo:searchUserVos){
            Friend friend = friendMapper.isFriend(tokenUid, searchUserVo.getId());
            if(friend!=null){
                searchUserVo.setIsfriend(true);
            }else {
                searchUserVo.setIsfriend(false);
            }
        }
        return R.ok().put("users",searchUserVos);
    }

    /**
     * 查询群 按照name 查询
     * @param request
     * @return
     */
    @RequestMapping("/querygroups")
    @Transactional
    public R queryGroups(HttpServletRequest request){
        String token = request.getParameter("token");
        final Long tokenUid = JwtUtils.getTokenUid(token);
        String key = request.getParameter("key");
        List<SearchGroupVo> searchGroupVos = groupMapper.searchGroups(key);
        for(SearchGroupVo vo:searchGroupVos){
            Member member = memberMapper.ifInGroup(vo.getId(), tokenUid);
            if(member==null){
                vo.setIngroup(false);
            }else {
                vo.setIngroup(true);
            }
        }
        return R.ok().put("groups",searchGroupVos);
    }


    /**
     * 发出添加好友的申请
     *
     * @param request
     * @return
     */
    @RequestMapping("/addfriend")
    public R applyAddFriend(HttpServletRequest request) {
        String token = request.getParameter("token");
        final Long currentUid = JwtUtils.getTokenUid(token);
        String friendusername = request.getParameter("friendusername");
        List<ChatUser> list = chatUserMapper.selectByUserName(friendusername);
        if (list != null && list.size() == 1) {
            ChatUser currentUser = chatUserMapper.selectById(currentUid);
            ChatUser friend = list.get(0);
            //如果不是好友了就继续
            if (friendMapper.isFriend(currentUid, friend.getId()) == null) {
                //如果之前已经发送过了 而且等待处理状态的
                List<ApplyAddfriend> applyAddfriends_wait = applyAddfriendMapper.selectWithFromAndToAndStatus(currentUid, friend.getId(), 0);
                if (applyAddfriends_wait == null || applyAddfriends_wait.size() == 0) {
                    ApplyAddfriend applyAddfriend = new ApplyAddfriend();
                    applyAddfriend.setFromId(currentUid);
                    applyAddfriend.setToId(friend.getId());
                    applyAddfriend.setStatus(0);
                    applyAddfriend.setCreateTime(new Date());
                    applyAddfriend.setIfToRead(0);
                    applyAddfriendMapper.insert(applyAddfriend);
                    Channel friendChannel = ConnPool.queryTCP(friend.getId());
                    if (friendChannel != null && friendChannel.isActive()) {
                        ApplyAddFriendNotice applyAddFriendNotice = new ApplyAddFriendNotice();
                        applyAddFriendNotice.setIfRead((byte) 0);
                        applyAddFriendNotice.setTimestamp(applyAddfriend.getCreateTime().getTime());
                        applyAddFriendNotice.setApplyAddFriendId(applyAddfriend.getId());
                        applyAddFriendNotice.setUserName(currentUser.getUsername());
                        applyAddFriendNotice.setUserNameLen((short) currentUser.getUsername().getBytes().length);
                        SendUtils.sendNotice(friendChannel, GlobalCode.Other_Apply_Add_You_Notice.getBizCode(), applyAddFriendNotice);
                    } else {
                        // TODO 放在等好友上线的时候 查询数据再发送通知
                    }
                } else {
                    R.error("曾经发出过请求了,还在等待对方验证中");
                }
            } else {
                return R.error("已经是好友了,无需申请添加");
            }
        } else {
            LOGGER.error("对方都不存在，无法申请添加!!!!");
            return R.error("添加的好友未在系统中！");
        }
        return R.ok();
    }

    /**
     * 申请如群
     * @param request
     * @return
     */
    @RequestMapping("/entergroup")
    @Transactional
    public R applyAddGroup(HttpServletRequest request){
        String token = request.getParameter("token");
        final Long currentUid = JwtUtils.getTokenUid(token);
        Long gid = Long.valueOf(request.getParameter("gid"));
        ChatGroup chatGroup = groupMapper.selectById(gid);
        if(chatGroup!=null){
            Member member = memberMapper.ifInGroup(gid, currentUid);
            if(member==null){
                List<ApplyEntergroup> applyEntergroups = applyEntergroupMapper.selectUnHandlerWithFidAndGid(currentUid, gid);
                if(applyEntergroups!=null && applyEntergroups.size()>0){
                    //之前已经申请过，直接修改创建时间
                    return R.ok();
                }else {
                    //之前没有申请过
                    ApplyEntergroup applyEntergroup=new ApplyEntergroup();
                    applyEntergroup.setFromId(currentUid);
                    applyEntergroup.setGroupId(gid);
                    applyEntergroup.setCreateTime(new Date());
                    applyEntergroup.setStatus(0);
                    applyEntergroup.setIfFromRead(0);
                    applyEntergroup.setIfToRead(0);
                    applyEntergroupMapper.insert(applyEntergroup);
                    Channel createrChannel = ConnPool.queryTCP(chatGroup.getCreater());
                    if(createrChannel!=null && createrChannel.isActive()){
                        //todo 对方申请入群
                        // 需要做2个Notice  对方申请入群，<===> 群主/群 接受或者拒绝你的申请
                    }
                    return R.ok();
                }
            }else{
                return  R.error("已经是群成员了，无需重复加群");
            }
        }else {
            return R.error("群不存在");
        }
    }



    /**
     * 查看我的好友申请列表  查看后把该人的未读全部设为已读
     *
     * @param request
     * @return
     */
    @RequestMapping("/lookmyapplyaddfriendlist")
    public R lookMyApplyAddFriendList(HttpServletRequest request) {
        String token = request.getParameter("token");
        final Long currentUid = JwtUtils.getTokenUid(token);
        List<ApplyAddfriend> applyAddfriends = applyAddfriendMapper.selectAboutMe(currentUid);
        List<MyApplyAddFriendVo> myApplyAddFriendVoList = new ArrayList<>(applyAddfriends.size());

        for (int i = 0; i < applyAddfriends.size(); i++) {
            ApplyAddfriend applyAddfriend = applyAddfriends.get(i);
            MyApplyAddFriendVo item = new MyApplyAddFriendVo();
            if (applyAddfriend.getFromId().longValue() == currentUid.longValue()) {
                ChatUser toUser = chatUserMapper.selectById(applyAddfriend.getToId());
                item.setUsername(toUser.getUsername());
                item.setNickname(toUser.getNickname());
                item.setApplytype((byte) 1);
                item.setStatus(applyAddfriend.getStatus().byteValue());
                item.setTimestamp(applyAddfriend.getCreateTime().getTime());
                item.setApplyaddfriendid(applyAddfriend.getId());
            }
            if (applyAddfriend.getFromId().longValue()!=currentUid.longValue()) {
                ChatUser fromUser = chatUserMapper.selectById(applyAddfriend.getFromId());
                item.setUsername(fromUser.getUsername());
                item.setNickname(fromUser.getNickname());
                item.setApplytype((byte) 0);
                item.setStatus(applyAddfriend.getStatus().byteValue());
                item.setTimestamp(applyAddfriend.getCreateTime().getTime());
                item.setApplyaddfriendid(applyAddfriend.getId());
            }
            myApplyAddFriendVoList.add(item);
        }
        setRead(currentUid);
        return R.ok().put("myapplyaddfriendlist", myApplyAddFriendVoList);
    }

    /**
     * 接受或者拒绝 对方的好友添加请求
     *
     * @param request
     * @return
     */
    @RequestMapping("/acceptoreject")
    public R acceptOrReject(HttpServletRequest request) {
        String token = request.getParameter("token");
        final Long currentUid = JwtUtils.getTokenUid(token);
        String operatype = request.getParameter("operatype");
        Integer operatype_int = Integer.valueOf(operatype);
        String applyaddfriendid = request.getParameter("applyaddfriendid");
        Long applyaddfriendid_long = Long.valueOf(applyaddfriendid);
        ApplyAddfriend applyAddfriend = applyAddfriendMapper.selectById(applyaddfriendid_long);
        Date date = new Date();
        if (!applyAddfriend.getToId().equals(currentUid)) {
            LOGGER.error("当前用户和申请表的接受方用户不一致！！");
            return R.error("当前用户无法操作这条申请记录");
        }
        if (operatype_int.equals(0)) {
            //拒绝
            applyAddfriend.setStatus(-1);
            applyAddfriend.setEndTime(date);
            applyAddfriendMapper.updateById(applyAddfriend);
        }
        if (operatype_int.equals(1)) {
            //接受
            applyAddfriend.setStatus(1);
            applyAddfriend.setEndTime(date);
            applyAddfriendMapper.updateById(applyAddfriend);
            boolean b = becomeFriend(applyAddfriend.getFromId(), applyAddfriend.getToId());
            if (b) {
                Long fromUid = applyAddfriend.getFromId();
                Channel fromChannel = ConnPool.queryTCP(fromUid);
                if (fromChannel != null && fromChannel.isActive()) {
                    ChatUser currentUser = chatUserMapper.selectById(currentUid);
                    AcceptOrRejectFriendNotice acceptOrRejectFriendNotice = new AcceptOrRejectFriendNotice();
                    acceptOrRejectFriendNotice.setApplyAddFriendId(applyaddfriendid_long);
                    acceptOrRejectFriendNotice.setIfRead((byte) 0x00);
                    acceptOrRejectFriendNotice.setOperateTimestamp(date.getTime());
                    acceptOrRejectFriendNotice.setOperateType(operatype_int.byteValue());
                    acceptOrRejectFriendNotice.setUserName(currentUser.getUsername());
                    acceptOrRejectFriendNotice.setUserNameLen((short) currentUser.getUsername().getBytes().length);
                    SendUtils.sendNotice(fromChannel, GlobalCode.Other_Add_Or_Reject_Notice.getBizCode(), acceptOrRejectFriendNotice);
                }
            }
            //TODO 终端请求更新好友列表或者服务器主动推送
        }

        return R.ok();
    }

    /**
     * 成为朋友
     *
     * @param fromUid
     * @param toUid
     * @return
     */
    @Transactional
    public boolean becomeFriend(Long fromUid, Long toUid) {
        ChatUser from = chatUserMapper.selectById(fromUid);
        ChatUser to = chatUserMapper.selectById(toUid);
        Friend friend = friendMapper.isFriend(fromUid, toUid);
        if (friend == null) {
            Date date = new Date();
            Friend friend1 = new Friend();
            friend1.setCreateTime(date);
            friend1.setUserId(fromUid);
            friend1.setFriendId(toUid);
            friend1.setfRemark(to.getNickname());
            friendMapper.insert(friend1);
            Friend friend2 = new Friend();
            friend2.setCreateTime(date);
            friend2.setUserId(toUid);
            friend2.setFriendId(fromUid);
            friend2.setfRemark(from.getNickname());
            friendMapper.insert(friend2);
            return true;
        } else {
            LOGGER.error("卧槽，已经是朋友了，怎么还有添加好友的申请记录了？？？");
            return false;
        }
    }

    @Transactional
    public void setRead(Long currentUid) {
        applyAddfriendMapper.updateAddMeHasRead(currentUid);
        applyAddfriendMapper.updateOtherRejectOrAcceptHasRead(currentUid);
    }


}
